extern int main();
extern void SystemInit();

void handle_reset();
/*
naked 属性 告诉编译器 不生成 压栈汇编 push 等指令

 0x00-0x03 _start  跳转到reset_func
 0x04-0x08 _vector 中断向量表
 */

// 复位函数
__attribute__((section(".init"), naked)) void _start();
void _start()
{
	handle_reset();
}

/***********************中断向量声明******************************* */
//  声明 中断函数 防止编译器报错
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif

__WEAK void NMI_Handler()
{
	while (1)
		;
} /* NMI */
__WEAK void HardFault_Handler()
{
	while (1)
		;
} /* Hard Fault */

__WEAK void Ecall_M_Mode_Handler() {}		/* Ecall M Mode */
__WEAK void Ecall_U_Mode_Handler() {}		/* Ecall U Mode */
__WEAK void Break_Point_Handler() {}		/* Break Point */
__WEAK void SysTick_Handler() {}			/* SysTick */
__WEAK void SW_Handler() {}					/* SW */
__WEAK void WWDG_IRQHandler() {}			/* Window Watchdog */
__WEAK void PVD_IRQHandler() {}				/* PVD through EXTI Line detect */
__WEAK void TAMPER_IRQHandler() {}			/* TAMPER */
__WEAK void RTC_IRQHandler() {}				/* RTC */
__WEAK void FLASH_IRQHandler() {}			/* Flash */
__WEAK void RCC_IRQHandler() {}				/* RCC */
__WEAK void EXTI0_IRQHandler() {}			/* EXTI Line 0 */
__WEAK void EXTI1_IRQHandler() {}			/* EXTI Line 1 */
__WEAK void EXTI2_IRQHandler() {}			/* EXTI Line 2 */
__WEAK void EXTI3_IRQHandler() {}			/* EXTI Line 3 */
__WEAK void EXTI4_IRQHandler() {}			/* EXTI Line 4 */
__WEAK void DMA1_Channel1_IRQHandler() {}	/* DMA1 Channel 1 */
__WEAK void DMA1_Channel2_IRQHandler() {}	/* DMA1 Channel 2 */
__WEAK void DMA1_Channel3_IRQHandler() {}	/* DMA1 Channel 3 */
__WEAK void DMA1_Channel4_IRQHandler() {}	/* DMA1 Channel 4 */
__WEAK void DMA1_Channel5_IRQHandler() {}	/* DMA1 Channel 5 */
__WEAK void DMA1_Channel6_IRQHandler() {}	/* DMA1 Channel 6 */
__WEAK void DMA1_Channel7_IRQHandler() {}	/* DMA1 Channel 7 */
__WEAK void ADC1_2_IRQHandler() {}			/* ADC1_2 */
__WEAK void USB_HP_CAN1_TX_IRQHandler() {}	/* USB HP and CAN1 TX */
__WEAK void USB_LP_CAN1_RX0_IRQHandler() {} /* USB LP and CAN1RX0 */
__WEAK void CAN1_RX1_IRQHandler() {}		/* CAN1 RX1 */
__WEAK void CAN1_SCE_IRQHandler() {}		/* CAN1 SCE */
__WEAK void EXTI9_5_IRQHandler() {}			/* EXTI Line 9..5 */
__WEAK void TIM1_BRK_IRQHandler() {}		/* TIM1 Break */
__WEAK void TIM1_UP_IRQHandler() {}			/* TIM1 Update */
__WEAK void TIM1_TRG_COM_IRQHandler() {}	/* TIM1 Trigger and Commutation */
__WEAK void TIM1_CC_IRQHandler() {}			/* TIM1 Capture Compare */
__WEAK void TIM2_IRQHandler() {}			/* TIM2 */
__WEAK void TIM3_IRQHandler() {}			/* TIM3 */
__WEAK void TIM4_IRQHandler() {}			/* TIM4 */
__WEAK void I2C1_EV_IRQHandler() {}			/* I2C1 Event */
__WEAK void I2C1_ER_IRQHandler() {}			/* I2C1 Error */
__WEAK void I2C2_EV_IRQHandler() {}			/* I2C2 Event */
__WEAK void I2C2_ER_IRQHandler() {}			/* I2C2 Error */
__WEAK void SPI1_IRQHandler() {}			/* SPI1 */
__WEAK void SPI2_IRQHandler() {}			/* SPI2 */
__WEAK void USART1_IRQHandler() {}			/* USART1 */
__WEAK void USART2_IRQHandler() {}			/* USART2 */
__WEAK void USART3_IRQHandler() {}			/* USART3 */
__WEAK void EXTI15_10_IRQHandler() {}		/* EXTI Line 15..10 */
__WEAK void RTCAlarm_IRQHandler() {}		/* RTC Alarm through EXTI Line */
__WEAK void USBWakeUp_IRQHandler() {}		/* USB Wakeup from suspend */
__WEAK void TIM8_BRK_IRQHandler() {}		/* TIM8 Break */
__WEAK void TIM8_UP_IRQHandler() {}			/* TIM8 Update */
__WEAK void TIM8_TRG_COM_IRQHandler() {}	/* TIM8 Trigger and Commutation */
__WEAK void TIM8_CC_IRQHandler() {}			/* TIM8 Capture Compare */
__WEAK void RNG_IRQHandler() {}				/* RNG */
__WEAK void SDIO_IRQHandler() {}			/* SDIO */
__WEAK void TIM5_IRQHandler() {}			/* TIM5 */
__WEAK void SPI3_IRQHandler() {}			/* SPI3 */
__WEAK void UART4_IRQHandler() {}			/* UART4 */
__WEAK void UART5_IRQHandler() {}			/* UART5 */
__WEAK void TIM6_IRQHandler() {}			/* TIM6 */
__WEAK void TIM7_IRQHandler() {}			/* TIM7 */
__WEAK void DMA2_Channel1_IRQHandler() {}	/* DMA2 Channel 1 */
__WEAK void DMA2_Channel2_IRQHandler() {}	/* DMA2 Channel 2 */
__WEAK void DMA2_Channel3_IRQHandler() {}	/* DMA2 Channel 3 */
__WEAK void DMA2_Channel4_IRQHandler() {}	/* DMA2 Channel 4 */
__WEAK void DMA2_Channel5_IRQHandler() {}	/* DMA2 Channel 5 */
__WEAK void ETH_IRQHandler() {}				/* ETH */
__WEAK void ETH_WKUP_IRQHandler() {}		/* ETH WakeUp */
__WEAK void CAN2_TX_IRQHandler() {}			/* CAN2 TX */
__WEAK void CAN2_RX0_IRQHandler() {}		/* CAN2 RX0 */
__WEAK void CAN2_RX1_IRQHandler() {}		/* CAN2 RX1 */
__WEAK void CAN2_SCE_IRQHandler() {}		/* CAN2 SCE */
__WEAK void USBFS_IRQHandler() {}			/* USBFS */
__WEAK void USBHSWakeup_IRQHandler() {}		/* USBHS Wakeup */
__WEAK void USBHS_IRQHandler() {}			/* USBHS */
__WEAK void DVP_IRQHandler() {}				/* DVP */
__WEAK void UART6_IRQHandler() {}			/* UART6 */
__WEAK void UART7_IRQHandler() {}			/* UART7 */
__WEAK void UART8_IRQHandler() {}			/* UART8 */
__WEAK void TIM9_BRK_IRQHandler() {}		/* TIM9 Break */
__WEAK void TIM9_UP_IRQHandler() {}			/* TIM9 Update */
__WEAK void TIM9_TRG_COM_IRQHandler() {}	/* TIM9 Trigger and Commutation */
__WEAK void TIM9_CC_IRQHandler() {}			/* TIM9 Capture Compare */
__WEAK void TIM10_BRK_IRQHandler() {}		/* TIM10 Break */
__WEAK void TIM10_UP_IRQHandler() {}		/* TIM10 Update */
__WEAK void TIM10_TRG_COM_IRQHandler() {}	/* TIM10 Trigger and Commutation */
__WEAK void TIM10_CC_IRQHandler() {}		/* TIM10 Capture Compare */
__WEAK void DMA2_Channel6_IRQHandler() {}	/* DMA2 Channel 6 */
__WEAK void DMA2_Channel7_IRQHandler() {}	/* DMA2 Channel 7 */
__WEAK void DMA2_Channel8_IRQHandler() {}	/* DMA2 Channel 8 */
__WEAK void DMA2_Channel9_IRQHandler() {}	/* DMA2 Channel 9 */
__WEAK void DMA2_Channel10_IRQHandler() {}	/* DMA2 Channel 10 */
__WEAK void DMA2_Channel11_IRQHandler() {}	/* DMA2 Channel 11 */

/*中断向量表 占用data 区*/

__attribute__((section(".vector"))) const void *_vector_base[] = {

	_start,
	0,
	NMI_Handler,	   /* NMI */
	HardFault_Handler, /* Hard Fault */
	0,
	Ecall_M_Mode_Handler, /* Ecall M Mode */
	0,
	0,
	Ecall_U_Mode_Handler, /* Ecall U Mode */
	Break_Point_Handler,  /* Break Point */
	0,
	0,
	SysTick_Handler, /* SysTick */
	0,
	SW_Handler, /* SW */
	0,
	/* External Interrupts */
	WWDG_IRQHandler,			/* Window Watchdog */
	PVD_IRQHandler,				/* PVD through EXTI Line detect */
	TAMPER_IRQHandler,			/* TAMPER */
	RTC_IRQHandler,				/* RTC */
	FLASH_IRQHandler,			/* Flash */
	RCC_IRQHandler,				/* RCC */
	EXTI0_IRQHandler,			/* EXTI Line 0 */
	EXTI1_IRQHandler,			/* EXTI Line 1 */
	EXTI2_IRQHandler,			/* EXTI Line 2 */
	EXTI3_IRQHandler,			/* EXTI Line 3 */
	EXTI4_IRQHandler,			/* EXTI Line 4 */
	DMA1_Channel1_IRQHandler,	/* DMA1 Channel 1 */
	DMA1_Channel2_IRQHandler,	/* DMA1 Channel 2 */
	DMA1_Channel3_IRQHandler,	/* DMA1 Channel 3 */
	DMA1_Channel4_IRQHandler,	/* DMA1 Channel 4 */
	DMA1_Channel5_IRQHandler,	/* DMA1 Channel 5 */
	DMA1_Channel6_IRQHandler,	/* DMA1 Channel 6 */
	DMA1_Channel7_IRQHandler,	/* DMA1 Channel 7 */
	ADC1_2_IRQHandler,			/* ADC1_2 */
	USB_HP_CAN1_TX_IRQHandler,	/* USB HP and CAN1 TX */
	USB_LP_CAN1_RX0_IRQHandler, /* USB LP and CAN1RX0 */
	CAN1_RX1_IRQHandler,		/* CAN1 RX1 */
	CAN1_SCE_IRQHandler,		/* CAN1 SCE */
	EXTI9_5_IRQHandler,			/* EXTI Line 9..5 */
	TIM1_BRK_IRQHandler,		/* TIM1 Break */
	TIM1_UP_IRQHandler,			/* TIM1 Update */
	TIM1_TRG_COM_IRQHandler,	/* TIM1 Trigger and Commutation */
	TIM1_CC_IRQHandler,			/* TIM1 Capture Compare */
	TIM2_IRQHandler,			/* TIM2 */
	TIM3_IRQHandler,			/* TIM3 */
	TIM4_IRQHandler,			/* TIM4 */
	I2C1_EV_IRQHandler,			/* I2C1 Event */
	I2C1_ER_IRQHandler,			/* I2C1 Error */
	I2C2_EV_IRQHandler,			/* I2C2 Event */
	I2C2_ER_IRQHandler,			/* I2C2 Error */
	SPI1_IRQHandler,			/* SPI1 */
	SPI2_IRQHandler,			/* SPI2 */
	USART1_IRQHandler,			/* USART1 */
	USART2_IRQHandler,			/* USART2 */
	USART3_IRQHandler,			/* USART3 */
	EXTI15_10_IRQHandler,		/* EXTI Line 15..10 */
	RTCAlarm_IRQHandler,		/* RTC Alarm through EXTI Line */
	USBWakeUp_IRQHandler,		/* USB Wakeup from suspend */
	TIM8_BRK_IRQHandler,		/* TIM8 Break */
	TIM8_UP_IRQHandler,			/* TIM8 Update */
	TIM8_TRG_COM_IRQHandler,	/* TIM8 Trigger and Commutation */
	TIM8_CC_IRQHandler,			/* TIM8 Capture Compare */
	RNG_IRQHandler,				/* RNG */
	0,
	SDIO_IRQHandler,		   /* SDIO */
	TIM5_IRQHandler,		   /* TIM5 */
	SPI3_IRQHandler,		   /* SPI3 */
	UART4_IRQHandler,		   /* UART4 */
	UART5_IRQHandler,		   /* UART5 */
	TIM6_IRQHandler,		   /* TIM6 */
	TIM7_IRQHandler,		   /* TIM7 */
	DMA2_Channel1_IRQHandler,  /* DMA2 Channel 1 */
	DMA2_Channel2_IRQHandler,  /* DMA2 Channel 2 */
	DMA2_Channel3_IRQHandler,  /* DMA2 Channel 3 */
	DMA2_Channel4_IRQHandler,  /* DMA2 Channel 4 */
	DMA2_Channel5_IRQHandler,  /* DMA2 Channel 5 */
	ETH_IRQHandler,			   /* ETH */
	ETH_WKUP_IRQHandler,	   /* ETH WakeUp */
	CAN2_TX_IRQHandler,		   /* CAN2 TX */
	CAN2_RX0_IRQHandler,	   /* CAN2 RX0 */
	CAN2_RX1_IRQHandler,	   /* CAN2 RX1 */
	CAN2_SCE_IRQHandler,	   /* CAN2 SCE */
	USBFS_IRQHandler,		   /* USBFS */
	USBHSWakeup_IRQHandler,	   /* USBHS Wakeup */
	USBHS_IRQHandler,		   /* USBHS */
	DVP_IRQHandler,			   /* DVP */
	UART6_IRQHandler,		   /* UART6 */
	UART7_IRQHandler,		   /* UART7 */
	UART8_IRQHandler,		   /* UART8 */
	TIM9_BRK_IRQHandler,	   /* TIM9 Break */
	TIM9_UP_IRQHandler,		   /* TIM9 Update */
	TIM9_TRG_COM_IRQHandler,   /* TIM9 Trigger and Commutation */
	TIM9_CC_IRQHandler,		   /* TIM9 Capture Compare */
	TIM10_BRK_IRQHandler,	   /* TIM10 Break */
	TIM10_UP_IRQHandler,	   /* TIM10 Update */
	TIM10_TRG_COM_IRQHandler,  /* TIM10 Trigger and Commutation */
	TIM10_CC_IRQHandler,	   /* TIM10 Capture Compare */
	DMA2_Channel6_IRQHandler,  /* DMA2 Channel 6 */
	DMA2_Channel7_IRQHandler,  /* DMA2 Channel 7 */
	DMA2_Channel8_IRQHandler,  /* DMA2 Channel 8 */
	DMA2_Channel9_IRQHandler,  /* DMA2 Channel 9 */
	DMA2_Channel10_IRQHandler, /* DMA2 Channel 10 */
	DMA2_Channel11_IRQHandler  /* DMA2 Channel 11 */
};

void handle_reset()
// void _start()
{
	extern unsigned int _data_lma, _sdata, _edata, _sbss, _ebss;

	unsigned int *sdata;		// 0x20000000
	unsigned int *data_atflash; // 0x80000xx

	asm("la sp, _eusrstack");
	// copy data from flash to sram
	sdata = &_sdata;            // 0x20000000
	data_atflash = &_data_lma;  // 0x80000xx
	while (sdata < &_edata)
	{
		*sdata++ = *data_atflash++;
	}

	/*clear bss*/
	sdata = &_sbss;
	while (sdata < &_ebss)
	{
		*sdata++ = 0;
	}

	/* Configure pipelining and instruction prediction */
	asm("li t0, 0x1f");
	asm("csrw 0xbc0, t0");

	/* Enable interrupt nesting and hardware stack */
	asm("li t0, 0x1f");
	asm("csrw 0x804, t0");

	/* Enable floating point and global interrupt, configure privileged mode */
	asm("li t0, 0x7800"); //一直是机器模式 硬件FPU打开 QingKeV4F 
	asm("csrw mstatus, t0");

	/* Configure the interrupt vector table recognition mode and entry address mode */
	asm("la t0, _vector_base");
	asm("ori t0, t0, 3");
	asm("csrw mtvec, t0");

	SystemInit();
	// main();
	asm("la t0, main");
	asm("csrw mepc, t0");
	asm("mret");
}